package com.amit.Contollers;

import com.amit.client.domain.StudentVO;
import com.amit.entities.StudentEntity;
import com.amit.services.StudentService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({"UnusedDeclaration", "SpringJavaAutowiringInspection"})
@Controller
@RequestMapping(value = "/student")
public final class StudentController {

    private Logger logger = Logger.getLogger(this.getClass());

    private ObjectMapper mapper;

    @Autowired
    private StudentService service;

    public StudentController() {
        mapper = new ObjectMapper();
    }

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<String> addStudent(@RequestBody StudentVO studentVO) {
        if (studentVO == null || StringUtils.isEmpty(studentVO.getFirstName()) || StringUtils.isEmpty(studentVO.getLastName())) {
            logger.error("student name or last name can't be empty");
            return new ResponseEntity<>("student name or last name can't be empty", HttpStatus.BAD_REQUEST);
        }
        return new ResponseEntity<>(service.addStudent(studentVO.getFirstName(), studentVO.getLastName()).toString(), HttpStatus.CREATED);
    }

    @RequestMapping(value = "/{studentId}", method = RequestMethod.DELETE)
    @ResponseBody
    public ResponseEntity<String> removeStudent(@PathVariable("studentId") Long studentId) {
        if (studentId == null) {
            logger.error("student id can't be empty");
            return new ResponseEntity<>("student id can't be empty", HttpStatus.BAD_REQUEST);
        }
        service.removeStudent(studentId);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> readAllStudents() throws IOException {
        List<StudentEntity> students = service.readAllStudents();
        List<StudentVO> studentVOs = new ArrayList<>();
        if (students == null) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        for (StudentEntity student : students) {
            StudentVO studentVO = new StudentVO();
            studentVO.setFirstName(student.getFirstName());
            studentVO.setLastName(student.getLastName());
            studentVO.setId(student.getId());
            studentVOs.add(studentVO);
        }
        return new ResponseEntity<>(mapper.writeValueAsString(studentVOs), HttpStatus.OK);
    }

    @RequestMapping(value = "/{studentId}", method = RequestMethod.GET)
    public ResponseEntity<String> readStudent(@PathVariable("studentId") Long studentId) throws IOException {
        if (studentId == null) {
            logger.error("student id can't be empty");
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        StudentVO studentVO = new StudentVO();
        StudentEntity student = service.readStudent(studentId);
        studentVO.setFirstName(student.getFirstName());
        studentVO.setLastName(student.getLastName());
        studentVO.setId(student.getId());
        return new ResponseEntity<>(mapper.writeValueAsString(studentVO), HttpStatus.OK);
    }

    @ExceptionHandler(value = RuntimeException.class)
    public void handleExceptions(RuntimeException rte, HttpServletResponse response) throws IOException {
        if (response == null) {
            logger.error(rte.getMessage(), rte);
            return;
        }
        if (rte == null) {
            logger.error("unknown exception");
            response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
            return;
        }
        logger.error(rte.getMessage(), rte);
        response.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}
